package com.zrz.util;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
import com.zrz.XmlUtils.CommonUtil;
import com.zrz.model.auto.User;
import com.zrz.vo.Token;
import com.zrz.wechart.WeiXinResult;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Value;

import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.UUID;



public  class WeiXinUtils {
    // 临时二维码
    private final static String QR_SCENE = "QR_SCENE";
    // 永久二维码
    private final static String QR_LIMIT_SCENE = "QR_LIMIT_SCENE";
    // 永久二维码(字符串)
    private final static String QR_LIMIT_STR_SCENE = "QR_LIMIT_STR_SCENE";
    // 创建二维码
    private final static String create_ticket_path = "https://api.weixin.qq.com/cgi-bin/qrcode/create";
    // 通过ticket换取二维码
    private final static String showqrcode_path = "https://mp.weixin.qq.com/cgi-bin/showqrcode";



    public User getUserInfo(String code,String appId,String secret) {
        User user = new User();
        String requestUrl = String.format("https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code", appId,secret, code);
        String result = HttpUtils.okGet(requestUrl);
        LogUtils.info(result);
        try {
            JsonObject jsonObject = new Gson().fromJson(result, JsonObject.class);
            if (jsonObject.has("openid")) {
                String openid = jsonObject.get("openid").getAsString();
                if (jsonObject.has("access_token")) {
                    String accessToken = jsonObject.get("access_token").getAsString();
                    requestUrl = String.format("https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN ", accessToken, openid);
                    result = HttpUtils.okGet(requestUrl);
                    LogUtils.info("获取用户信息"+result);
                    jsonObject = new Gson().fromJson(result, JsonObject.class);
                    if(jsonObject.has("unionid")){
                        LogUtils.info("获取用户uinionid"+jsonObject.get("unionid"));
                        user.setUnionid(jsonObject.get("unionid").getAsString());
                    }
                    LogUtils.info("jsonobject===="+jsonObject);
                    user.setNickname(jsonObject.get("nickname").getAsString());
                    user.setAvatar(jsonObject.get("headimgurl").getAsString());
                    user.setSex(jsonObject.get("sex").getAsInt());
                    user.setOpenId(jsonObject.get("openid").getAsString());
                    user.setProvince(jsonObject.get("province").getAsString());
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return user;
    }
    /**
     * 创建临时带参数二维码
     * @param accessToken
     * @expireSeconds 该二维码有效时间，以秒为单位。 最大不超过2592000（即30天），此字段如果不填，则默认有效期为30秒。
     * @param sceneId 场景Id
     * @return
     */
    public static String createTempTicket(String accessToken, String expireSeconds, int sceneId) {
//        WeiXinQRCode wxQRCode = null;

        TreeMap<String,String> params = new TreeMap<String,String>();
        params.put("access_token", accessToken);
        Map<String,Integer> intMap = new HashMap<String,Integer>();
        intMap.put("scene_id",sceneId);
        Map<String,Map<String,Integer>> mapMap = new HashMap<String,Map<String,Integer>>();
        mapMap.put("scene", intMap);
        //
        Map<String,Object> paramsMap = new HashMap<String,Object>();
        paramsMap.put("expire_seconds", expireSeconds);
        paramsMap.put("action_name", QR_SCENE);
        paramsMap.put("action_info", mapMap);
        String data = new Gson().toJson(paramsMap);
        data = HttpRequestUtil.HttpsDefaultExecute(HttpRequestUtil.POST_METHOD,create_ticket_path,params,data);
        try {
            LogUtils.info("tiken"+data);
        } catch (JsonSyntaxException e) {
            e.printStackTrace();
        }
        return null;

    }

    /**
     * 创建永久二维码(数字)
     * @param accessToken
     * @param sceneId 场景Id
     * @return
     */
    public static String createForeverTicket(String accessToken, int sceneId) {

        TreeMap<String,String> params = new TreeMap<String,String>();
        params.put("access_token", accessToken);
        //output data
        Map<String,Integer> intMap = new HashMap<String,Integer>();
        intMap.put("scene_id",sceneId);
        Map<String,Map<String,Integer>> mapMap = new HashMap<String,Map<String,Integer>>();
        mapMap.put("scene", intMap);
        //
        Map<String,Object> paramsMap = new HashMap<String,Object>();
        paramsMap.put("action_name", QR_LIMIT_SCENE);
        paramsMap.put("action_info", mapMap);
        String data = new Gson().toJson(paramsMap);
        data =  HttpRequestUtil.HttpsDefaultExecute(HttpRequestUtil.POST_METHOD,create_ticket_path,params,data);
        return null;
    }

    /**
     * 创建永久二维码(字符串)
     *
     * @param accessToken
     * @param sceneStr 场景str
     * @return
     */
    public static String createForeverStrTicket(String accessToken, String sceneStr){
        TreeMap<String,String> params = new TreeMap<String,String>();
        params.put("access_token", accessToken);
        //output data
        Map<String,String> intMap = new HashMap<String,String>();
        intMap.put("scene_str",sceneStr);
        Map<String,Map<String,String>> mapMap = new HashMap<String,Map<String,String>>();
        mapMap.put("scene", intMap);

        Map<String,Object> paramsMap = new HashMap<String,Object>();
        paramsMap.put("action_name", QR_LIMIT_STR_SCENE);
        paramsMap.put("action_info", mapMap);
        String data = new Gson().toJson(paramsMap);
        data =  HttpRequestUtil.HttpsDefaultExecute(HttpRequestUtil.POST_METHOD,create_ticket_path,params,data);
        LogUtils.info("data==="+data);
        JSONObject jsonObject = JSONObject.fromObject(data);
        return jsonObject.get("ticket").toString();

    }

    /**
     * 获取二维码ticket后，通过ticket换取二维码图片
     * @param ticket
     * @param savePath  保存的路径,例如 F:\\test\test.jpg
     * @return      Result.success = true 表示下载图片下载成功
     */
    public static WeiXinResult showQrcode(String ticket, String savePath) throws Exception{
        TreeMap<String,String> params = new TreeMap<String,String>();
        params.put("ticket", HttpRequestUtil.urlEncode(ticket, HttpRequestUtil.DEFAULT_CHARSET));
        WeiXinResult result = HttpRequestUtil.downMeaterMetod(params,HttpRequestUtil.GET_METHOD,showqrcode_path,savePath);
        return result;
    }
    public static void main(String[]args) {

        String token = HttpRequestUtil.getAccessToken("wx90fa698910b7b66c", "c9e33765c9ed958c3e23eb68e20fc2dc");
        String tickt = createForeverStrTicket(token, "123");
        try {
            showQrcode(tickt, "test1.jpg");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public Map<String, Object> getWxConfig(String appId,String secret,String pageUrl) {
        Map<String, Object> ret = new HashMap<String, Object>();
        String access_token = "";
        String jsapi_ticket = "";
        String timestamp = Long.toString(System.currentTimeMillis() / 1000); // 必填，生成签名的时间戳
        String nonceStr = UUID.randomUUID().toString(); // 必填，生成签名的随机串
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" +appId + "&secret=" + secret;

        String result = HttpUtils.okGet(url);
        JsonObject jsonObject = new Gson().fromJson(result, JsonObject.class);
        if (jsonObject != null) {
            //要注意，access_token需要缓存
            access_token = jsonObject.get("access_token").getAsString();

            url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + access_token + "&type=jsapi";
            String jsapiResult = HttpUtils.okGet(url);
            JsonObject jsapiJsonObject = new Gson().fromJson(jsapiResult, JsonObject.class);
            if (jsapiJsonObject != null) {
                jsapi_ticket = jsapiJsonObject.get("ticket").getAsString();
            }
        }
        String signature = "";
        // 注意这里参数名必须全部小写，且必须有序
        String sign = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonceStr + "&timestamp=" + timestamp + "&url=" +pageUrl;
       LogUtils.info("sign=="+sign);
        try {
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(sign.getBytes("UTF-8"));
            signature = byteToHex(crypt.digest());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        LogUtils.info("signature"+signature);
        ret.put("appId", appId);
        ret.put("timestamp", timestamp);
        ret.put("nonceStr", nonceStr);
        ret.put("signature", signature);
        return ret;
    }


    /**
     * 方法名：byteToHex</br>
     * 详述：字符串加密辅助方法 </br>
     * 开发人员：souvc  </br>
     * 创建时间：2016-1-5  </br>
     *
     * @param hash
     * @return 说明返回值含义
     * @throws
     */
    private String byteToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash) {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;

    }

    public String  getUserInfoByOpenid(String openId,String appId,String secret){
        Token token=CommonUtil.getToken(appId,secret);
        String requestUrl = String.format("https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN ", token.getAccessToken(), openId);
        String result = HttpUtils.okGet(requestUrl);
        LogUtils.info("获取用户信息"+result);
        JsonObject jsonObject = new Gson().fromJson(result, JsonObject.class);
        if(jsonObject.has("unionid")){
            LogUtils.info("获取用户uinionid"+jsonObject.get("unionid"));
            return jsonObject.get("unionid").toString();
        }
        return null;
    }

}
